using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GameBaseFramework.Attribute;
using Unity.Mathematics;
using UnityEngine.Events;

namespace GameLogic.AbilitySystem.Attribute
{
    /// <summary>
    /// 基础属性集
    /// 本页用于写规则，即不同属性之间变化的规律
    /// </summary>
    [Serializable]
    [CreateAssetMenu(menuName = "数值系统/创建新的数值集")]
    public class BaseAttributeSet : AttributeSet
    {
        /// <summary>
        /// 暴露给表现层的接口，表示该数值集发生了变化
        /// </summary>
        [HideInInspector]
        public UnityEvent OnAttributeChanged = new();

        /// <summary>
        /// 数值变化之前会调用的事件，主要用于限制属性的范围，如当前生命、当前魔法，或者属性如果有最大值/最小值的话也写在这里
        /// </summary>
        /// <param name="type"></param>
        /// <param name="BaseValue"></param>
        /// <param name="CurrentValue"></param>
        protected override void PreModify(AttributeType type, ref float BaseValue, ref float CurrentValue)
        {
            base.PreModify(type, ref BaseValue, ref CurrentValue);
            switch (type)
            {
                case AttributeType.Health:
                    BaseValue = math.clamp(BaseValue, 0, GetAttribute(AttributeType.MaxHealth).BaseValue);
                    CurrentValue = math.clamp(CurrentValue, 0, GetAttribute(AttributeType.MaxHealth).CurrentValue);
                    break;
                case AttributeType.Mana:
                    BaseValue = math.clamp(BaseValue, 0, GetAttribute(AttributeType.MaxHealth).BaseValue);
                    CurrentValue = math.clamp(CurrentValue, 0, GetAttribute(AttributeType.MaxHealth).CurrentValue);
                    break;
                case AttributeType.Attack:
                    break;
                case AttributeType.Defense:
                    break;
                case AttributeType.Damage:
                    Modify(AttributeType.Health,
                        new AttributeModifier
                        {
                            type = AttributeType.Health,
                            targetType = TargetAttributeType.Current,
                            Operator = AttributeOperator.Add,
                            ModifyValue = -BaseValue * (1 - (Attributes[(int)AttributeType.Defense].CurrentValue * 0.06f))
                        });
                    BaseValue = CurrentValue = 0f;
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(type), type, null);
            }

        }

        /// <summary>
        /// 属性发生变化之后，主要用于属性A影响属性B
        /// </summary>
        /// <param name="type"></param>
        /// <param name="attribute"></param>
        protected override void PostModify(AttributeType type, FloatAttribute attribute)
        {
            base.PostModify(type, attribute);
            switch (type)
            {
                case AttributeType.Health:
                    break;
                case AttributeType.MaxHealth:
                    break;
                case AttributeType.Mana:
                    break;
                case AttributeType.MaxMana:
                    break;
                case AttributeType.Attack:
                    break;
                case AttributeType.Defense:
                    break;
                case AttributeType.Damage:
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(type), type, null);
            }

            OnAttributeChanged.Invoke();
        }
    }
}
